package cn.barudisshu.route;

import cn.barudisshu.http.HttpStatus;
import cn.barudisshu.http.Resource;
import cn.barudisshu.http.servlet.HttpRequest;
import cn.barudisshu.http.servlet.HttpResponse;
import cn.barudisshu.matcher.RestRequestMatch;
import cn.barudisshu.matcher.RestRequestMatcher;
import cn.barudisshu.matcher.StdRestRequestMatcher;
import cn.barudisshu.util.analysis.ParamAttribute;
import com.google.common.base.Optional;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;

/**
 * 简单实现的路由
 *
 * @author galudisu
 */
public final class Route {

    private final HttpStatus successStatus;

    private final String httpMethod;
    private final String pathPattern;
    private final Class<? extends Resource> resourceClass;
    private final Method method;
    private final List<String> allParamNames;
    private final int[] allLineNumbers;
    private final List<Class<?>> allParamTypes;
    private final List<Type> allGenericParamTypes;

    public Route(Class<? extends Resource> resourceClass, ParamAttribute paramAttribute, String httpMethod, String pathPattern, Method method) {
        this(HttpStatus.OK,resourceClass,paramAttribute,httpMethod,pathPattern,method);
    }


    public Route(HttpStatus successStatus, Class<? extends Resource> resourceClass, ParamAttribute paramAttribute, String httpMethod, String pathPattern, Method method) {
        this.successStatus = successStatus;
        this.httpMethod = httpMethod;
        this.pathPattern = pathPattern;
        this.resourceClass = resourceClass;
        this.method = method;

        this.allParamNames = paramAttribute.getNames();
        this.allLineNumbers = paramAttribute.getLines();
        this.allParamTypes = Arrays.asList(method.getParameterTypes());
        this.allGenericParamTypes = Arrays.asList(method.getGenericParameterTypes());

    }

    /**
     * @param req
     * @param res
     * @return
     */
    public Optional<? extends RestRequestMatch> match(HttpRequest req, HttpResponse res) {
        String path = req.getRestPath();
        RestRequestMatcher matcher = new StdRestRequestMatcher(httpMethod,pathPattern);
        return matcher.match(req.getHttpMethod(), path);
    }


    public HttpStatus getSuccessStatus() {
        return successStatus;
    }

    public String getHttpMethod() {
        return httpMethod;
    }

    public String getPathPattern() {
        return pathPattern;
    }

    public Class<? extends Resource> getResourceClass() {
        return resourceClass;
    }

    public Method getMethod() {
        return method;
    }

    public List<String> getAllParamNames() {
        return allParamNames;
    }

    public int[] getAllLineNumbers() {
        return allLineNumbers;
    }

    public List<Class<?>> getAllParamTypes() {
        return allParamTypes;
    }

    public List<Type> getAllGenericParamTypes() {
        return allGenericParamTypes;
    }
}
